package com.zm.admin.zmeng.controller;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.poi.excel.ExcelUtil;
import cn.hutool.poi.excel.ExcelWriter;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.zm.admin.annotation.SysLogTag;
import com.zm.admin.utils.ResultBean;
import com.zm.admin.zmeng.domain.ZmScheduleLog;
import com.zm.admin.zmeng.domain.ZmSysLog;
import com.zm.admin.zmeng.dto.SysLogDto;
import com.zm.admin.zmeng.mapper.ZmSysLogMapper;
import com.zm.admin.zmeng.service.ZmLogService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Random;

/***
 *
 * @Auther: MuYun
 * @Date: 2022/12/22 20:16
 * @Description： 日志相关的后台接口
 *
 */
@RestController
@RequestMapping("/log")
@Slf4j
public class LogController {

    @Resource
    private ZmSysLogMapper zmSysLogMapper;

    @Resource
    private ZmLogService zmLogService;

    @RequestMapping("/list")
    public ResultBean list(SysLogDto logDto){
        ResultBean resultBean=new ResultBean();
        Integer pageNo=1;
        Integer pageSize=10;
        try{
            QueryWrapper<ZmSysLog> wrapper = designQueryMapper(logDto);
            if(ObjectUtil.isNotEmpty(logDto.getPageNo())){
                pageNo=logDto.getPageNo();
            }
            if(ObjectUtil.isNotEmpty(logDto.getPageSize())){
                pageSize= logDto.getPageSize();
            }
            Page<ZmSysLog> page = zmLogService.page(new Page<>(pageNo, pageSize), wrapper);
            resultBean.setCode(ResultBean.CODE_SUCCESS).setData(page);
        }catch (Exception e){
            log.error("获取日志列表接口出错",e);
        }
        return resultBean;
    }

    /**
     * 用户excel导出
     * @param response
     */
    @RequestMapping("/export")
    @ResponseBody
    @SysLogTag(desc = " 系统日志excel导出")
    public ResultBean export(HttpServletResponse response){
        ResultBean resultBean=new ResultBean();
        QueryWrapper<ZmSysLog> wrapper=new QueryWrapper<>();
        ExcelWriter writer = ExcelUtil.getWriter();
        try {
            //不查id,密码，盐值，头像（因为是路径地址
            wrapper.select(ZmSysLog.class,i->!"id".equals(i.getColumn()));
            List<ZmSysLog> zmSysLogs = zmSysLogMapper.selectList(wrapper);
            if(zmSysLogs.size()!=0){
                //组装文件名
                SimpleDateFormat format=new SimpleDateFormat("yyyyMMdd");
                String time=format.format(new Date());
                String newFilename=time+new Random().nextInt(10000)+ ".xls";
                // 通过工具类创建writer，默认创建xls格式
                writer = ExcelUtil.getWriter();
                writer.addHeaderAlias("id", "编号");
                writer.addHeaderAlias("username", "操作人");
                writer.addHeaderAlias("userType", "操作人角色");
                writer.addHeaderAlias("description", "日志详情");
                writer.addHeaderAlias("logType", "日志类型");
                writer.addHeaderAlias("ip", "IP地址");
                writer.addHeaderAlias("method", "请求方法");
                writer.addHeaderAlias("resultCode", "请求状态");
                writer.addHeaderAlias("exceptionDetail", "异常信息");
                //借用，不然重新赋值进去还是Date格式，excel乱码
                writer.addHeaderAlias("result", "日志创建时间");
                // 合并10个单元格后的标题行，使用默认标题样式
                writer.merge(9, "系统日志信息");
                int index=0;
                Iterator<ZmSysLog> iterator = zmSysLogs.iterator();
                while(iterator.hasNext()){
                    ZmSysLog sysLog=iterator.next();
                    int i=index+1;
                    //组装编号
                    sysLog.setId(Integer.toString(i));
                    index++;
                    //状态改造
                    if("1".equals(sysLog.getLogType())){
                        sysLog.setLogType("系统日志");
                    }else {
                        sysLog.setLogType("登录日志");
                    }
                    if(StrUtil.isEmpty(sysLog.getExceptionDetail())){
                        sysLog.setExceptionDetail("未出现异常");
                    }
                    SimpleDateFormat format1=new SimpleDateFormat("yyyy-MM-dd HH:mm");
                    sysLog.setResult(format1.format(sysLog.getCreateTime()));
                }
                writer.setOnlyAlias(true);
                // 写到excel，使用默认样式，强制输出标题
                writer.write(zmSysLogs, true);
                //response为HttpServletResponse对象
                response.setContentType("application/vnd.ms-excel;charset=utf-8");
                ServletOutputStream out=response.getOutputStream();
                //out为OutputStream，需要写出到的目标流
                writer.flush(out);
                resultBean.setCode(ResultBean.CODE_SUCCESS);
            }
        }catch (Exception e){
            log.info("导出定时任务日志excel接口异常：{}",e);
            resultBean.setCode(ResultBean.CODE_ERROR).setMsg(e.getMessage());
        }
        finally {
            // 关闭writer，释放内存
            writer.close();
        }
        return resultBean;
    }

    private static QueryWrapper<ZmSysLog> designQueryMapper(SysLogDto logDto){
        QueryWrapper<ZmSysLog> wrapper=new QueryWrapper<>();
        if(StrUtil.isNotEmpty(logDto.getUsername())){
            wrapper.lambda().like(ZmSysLog::getUsername,logDto.getUsername());
        }
        if(StrUtil.isNotEmpty(logDto.getIp())){
            wrapper.lambda().like(ZmSysLog::getIp,logDto.getIp());
        }
        if(StrUtil.isNotEmpty(logDto.getUserType())){
            wrapper.lambda().eq(ZmSysLog::getUserType,logDto.getUserType());
        }
        if(StrUtil.isNotEmpty(logDto.getStartTime())){
            wrapper.lambda().ge(ZmSysLog::getCreateTime,logDto.getStartTime());
        }
        if(StrUtil.isNotEmpty(logDto.getEndTime())){
            wrapper.lambda().le(ZmSysLog::getCreateTime,logDto.getEndTime());
        }
        if(StrUtil.isNotEmpty(logDto.getResultCode())){
            wrapper.lambda().eq(ZmSysLog::getResultCode,logDto.getResultCode());
        }
        return wrapper;
    }
}
